<template>
  <a-select
    :placeholder="placeholder"
    :options="options"
    :loading="loading"
    :show-search="showSearch"
    option-filter-prop="label"
    :filter-option="filterOption"
    :getPopupContainer="getPopupContainer"
    v-bind="$attrs"
    v-on="listeners"
  >
  </a-select>
</template>

<script>
const isEmpty = obj => {
  return !obj || Object.keys(obj).length === 0
}
export default {
  name: 'AsyncSelect',
  props: {
    getPopupContainer: {
      type: Function,
      default: node => node.parentNode
    },
    showSearch: {
      type: Boolean,
      default: true
    },
    placeholder: {
      type: String,
      default: '请选择'
    },
    action: {
      type: String,
      required: true
    },
    props: {
      type: Object,
      default() {
        return {
          value: 'code',
          label: 'name'
        }
      }
    },
    params: {
      type: Object,
      default: () => ({})
    },
    linkage: {
      type: Object,
      default: null
    }
  },
  model: {
    prop: 'value',
    event: 'change'
  },
  data() {
    return {
      loading: false,
      originData: []
    }
  },
  created() {
    if (!this.linkage) {
      this.fetchList()
    }
  },
  methods: {
    filterOption(input, option) {
      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
    },
    fetchList() {
      if (!this.action) {
        this.$message.warning('请配置字典请求路径！')
      }
      let params = this.params
      if (this.linkage) {
        if (isEmpty(this.linkage)) {
          this.originData = []
          return
        }
        params = { ...params, ...this.linkage }
      }
      this.loading = true
      this.$http
        .get(this.action, {
          params
        })
        .then(res => {
          if (res.success && res.result) {
            this.originData = res.result
          }
        })
        .finally(() => {
          this.loading = false
        })
    }
  },
  computed: {
    options() {
      return this.originData && this.originData.length > 0
        ? this.originData.map(item => {
            const data = {}
            const { value, label } = this.props
            if (typeof value === 'function') {
              data.value = value(item)
            } else {
              data.value = item[value]
            }
            if (typeof label === 'function') {
              data.label = label(item)
            } else {
              data.label = item[label]
            }
            return data
          })
        : []
    },
    listeners() {
      const _listeners = { ...this.$listeners }
      delete _listeners['origin-change']
      return _listeners
    }
  },
  watch: {
    params: 'fetchList',
    linkage: {
      handler(val) {
        if (!isEmpty(val)) {
          this.fetchList()
        }
      },
      immediate: true
    },
    originData(val) {
      this.$emit('origin-change', val)
    }
  }
}
</script>

<style></style>
